import { useEffect } from "react";
import { message, Modal, notification, Progress, Tooltip } from "antd";
import { useState, useRef } from "react";
import "./index.scss";
import {
  getFileList,
  getFileLink,
  downloadFromOss,
  moveToBin,
  setFileNameApi,
} from "@/service/file/index";
import PreviewFile from "@/components/PreviewFile";
import { useDispatch, useSelector } from "react-redux";
// import { availableAtion } from "@/store/createAction";
import { dateFormat } from "@/utils/dateFormat";
import { formatImageSizeText } from "@/utils/index";
import PanTable from "@/components/PanTable";
import { useNavigate, useLocation } from "react-router";
import RenameModal from "@/components/PanTable/components/RenameModal";

const Content = () => {
  const token = JSON.parse(localStorage.getItem("userInfo"))?.token;
  const tableRef = useRef();
  const { confirm } = Modal;
  const dispatch = useDispatch();
  const navigate = useNavigate();
  const location = useLocation();
  const searchParams = useSelector(
    (state) => state.searchReducer?.searchParams
  );
  const [record, setRecord] = useState({});

  useEffect(() => {
    dispatch({
      type: "searchParams",
      search: location.search,
    });
    // uploadProps.data = {
    //   path: searchParams["path"] || "",
    // };
    setMultipleSelected([]);
  }, [location]);
  const uploadProps = {
    name: "file",
    // http://www.xwjblog.cn:2333/upload
    // action: "http://localhost:2333/upload",
    headers: {
      Authorization: "bearer " + token,
    },
    // data: {
    //   path: searchParams["path"] || "",
    // },
    // multiple: true,
    // directory: true,
  };

  let timer = null;
  const searchVal = useRef("");
  const handleSearch = (event) => {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      searchVal.current = event.target.value;
      state.pagination.current = 1;
      tableRef.current?.refreshTableList();
    }, 300);
  };

  const handleBatchDelete = () => {
    confirm({
      content: "此操作将当前选中文件移入回收站，确认吗？",
      okText: "确认",
      cancelText: "取消",
      async onOk() {
        const res = await moveToBin({
          params: { fileIds: multipleSelected, path: searchParams.path },
        });
        if (res.status !== 200) return message.error(res.msg);
        message.success("已批量移入回收站");
        setMultipleSelected([]);
        tableRef.current?.refreshTableList();
      },
    });
  };
  const handleDelete = async (row) => {
    const res = await moveToBin({
      params: { fileId: row._id, path: searchParams.path },
    });
    if (res.status !== 200) return message.error(res.msg);
    message.success("已移入回收站");
    tableRef.current?.refreshTableList();
  };

  const [modalVisible, setModalVisible] = useState(false);
  const [previewInfo, setPreviewInfo] = useState({});

  const titleMap = {
    pic: "图片预览",
    video: "视频预览",
    music: "音乐播放",
    doc: "文档预览",
  };

  const previewFile = async (row) => {
    if (row.isFolder) {
      navigate({
        pathname: location.pathname,
        search: `?path=${row.path === "/" ? row.path : `${row.path}/`}${
          row.fileInfo?.fileName
        }`,
      });
      // tableRef.current?.refreshTableList();
    } else {
      const getLinkRes = await getFileLink({ params: { key: row.key } });
      const title =
        (titleMap[row.fileInfo.fileIcon] || "文件查看") +
        `-${row.fileInfo.fileName}`;
      setPreviewInfo({ title, url: getLinkRes, file: row });
      setModalVisible(true);
    }
  };

  const handleBack = () => {
    navigate(-1);
  };
  const handlePreviewCancel = () => {
    setModalVisible(false);
  };

  const operateItem = ({ row }) => {
    const items = [
      {
        key: "rename",
        type: "link",
        text: "重命名",
        onClick: () => {
          if (row.isFolder) {
            return message.info("文件夹名暂时无法修改");
          }
          setRecord({ ...row });
          setRenameModalVisible(true);
        },
      },
    ];
    if (!row.isFolder) {
      items.push(
        ...[
          {
            key: "download",
            type: "link",
            text: "下载",
            disabled: disabledDownloadBtn,
            onClick: handleDownloadFile.bind(this, row),
          },
          // 后续可以往这里扩展
        ]
      );
    }
    items.push({
      key: "delete",
      title: `确定将该${row.isFolder ? "文件夹" : "文件"}移入回收站吗？`,
      text: "删除",
      onConfirm: handleDelete.bind(this, row),
    });
    return items;
  };
  const columns = [
    {
      title: "文件名",
      dataIndex: "fileInfo",
      key: "fileInfo",
      ellipsis: true,
      render: (text, row) => (
        <div className="file-name-icon" onClick={previewFile.bind(this, row)}>
          <Tooltip placement="topLeft" title={text.fileName}>
            <svg className="icon" aria-hidden="true">
              <use xlinkHref={`#icon-${text.fileIcon}`}></use>
            </svg>
            <span>{text.fileName}</span>
          </Tooltip>
        </div>
      ),
    },
    {
      title: "类型",
      dataIndex: "fileType",
      key: "fileType",
      render: (text) => {
        return text ? text : "-";
      },
    },
    {
      title: "大小",
      dataIndex: "fileSize",
      key: "fileSize",
      render: (text) => {
        return text ? formatImageSizeText(text) : "-";
      },
    },
    {
      title: "创建日期",
      dataIndex: "time",
      key: "time",
      width: 220,
      render: (text) => {
        return dateFormat(text?.create, "yyyy-MM-dd hh:mm:ss");
      },
    },
    {
      title: "操作",
      key: "operate",
      fixed: "right",
      width: 170,
    },
  ];

  const [renameModalVisible, setRenameModalVisible] = useState(false);
  const handleRename = async (data) => {
    const { id, path, isFolder, name } = data;
    const params = {
      fileId: id,
      path,
      isFolder,
      name,
    };
    const res = await setFileNameApi({ params });
    tableRef.current?.refreshTableList();
    if (res.status !== 0) {
      message.success("修改成功");
      setRenameModalVisible(false);
    } else {
      message.error(res.msg);
    }
  };

  const [disabledDownloadBtn, setDisabledDownloadBtn] = useState(false);
  const [downloadProgress, setDownloadProgress] = useState(0);
  const key = "downloadProgress";
  const [fileName, setFileName] = useState("");
  const openDownloadNotification = (fileName) => {
    setFileName(fileName);
    notification["info"]({
      key,
      message: `${fileName} 正在拼命下载中`,
      description: <Progress percent={downloadProgress} />,
      duration: null,
    });
  };
  useEffect(() => {
    if (downloadProgress) {
      notification.open({
        key,
        message: `${fileName} 正在拼命下载中`,
        description: <Progress percent={downloadProgress} />,
        duration: null,
      });
      if (downloadProgress === 100) {
        setTimeout(() => {
          notification.close(key);
        }, 2000);
      }
    }
  }, [downloadProgress]);
  const handleDownloadFile = async (row) => {
    if (row.isFolder) {
    } else {
      openDownloadNotification(`${row.fileInfo?.fileName}.${row.fileType}`);
      setDisabledDownloadBtn(true);
      try {
        const getLinkRes = await getFileLink({ params: { key: row.key } });
        const getFileFromOssRes = await downloadFromOss({
          params: { url: getLinkRes },
          callback: (progressEvent) => {
            setDownloadProgress(() =>
              Math.round((progressEvent.loaded / progressEvent.total) * 100)
            );
          },
        });
        const blob = new Blob([getFileFromOssRes], {
          type: "application/octet-stream",
          "Content-Disposition": "attachment",
        });
        // 将 Blob 对象转为 url
        const url = window.URL.createObjectURL(blob);
        let a = document.createElement("a");
        a.href = url;
        a.download = `${row.fileInfo?.fileName}.${row.fileType}`;
        a.click();
      } catch (err) {
        message.error(err);
      } finally {
        setDisabledDownloadBtn(false);
      }
    }
  };

  const tableData = [];
  let [multipleSelected, setMultipleSelected] = useState([]);
  const onSelectChange = (newSelectedRowKeys) => {
    setMultipleSelected(newSelectedRowKeys);
  };
  const onPaginationChange = (newPage) => {
    state.pagination.current = newPage;
    setState(state);
    tableRef.current?.refreshTableList();
  };
  const [state, setState] = useState({
    rowKey: "_id",
    rowSelection: {
      preserveSelectedRowKeys: true,
      onChange: onSelectChange,
    },
    pagination: {
      current: 1,
      size: 7,
      total: 0,
      showQuickJumper: true,
      onChange: onPaginationChange,
    },
    loading: true,
  });
  const fileList = async ({ subfix }) => {
    const params = {
      fileGroup: subfix === "all" ? "" : subfix,
      keyword: searchVal.current,
      page: state.pagination.current,
      size: state.pagination.size,
    };
    // todo 暂时通过location.search条件限制来解决返回不了第一级目录的bug
    if (searchParams.path && location.search) {
      params["path"] = searchParams.path;
    }
    const res = await getFileList({
      method: "get",
      params: { ...params },
    });
    state.pagination.total = res.total;
    return res;
  };

  return (
    <div className="content-box">
      <PanTable
        ref={tableRef}
        state={state}
        datasource={tableData}
        columns={columns}
        fetch={fileList}
        uploadProps={uploadProps}
        search={handleSearch}
        hasRefresh={true}
        hasAddFolder={true}
        hasUploadDrawer={true}
        back={handleBack}
        batchDelete={{
          disabled: !multipleSelected.length,
          onClick: handleBatchDelete,
        }}
        operateItem={operateItem}
      ></PanTable>
      <PreviewFile
        visible={modalVisible}
        previewInfo={previewInfo}
        onCancel={handlePreviewCancel}
      ></PreviewFile>
      <RenameModal
        title="更改文件(夹)名"
        record={record}
        isOpenRenameModal={renameModalVisible}
        setOpen={setRenameModalVisible}
        onOk={handleRename}
      ></RenameModal>
    </div>
  );
};
export default Content;
